from datetime import datetime, time, timedelta
import random
import pandas as pd
import numpy as np
import logging
logging.basicConfig(level=logging.INFO)

def generate_leave_data(attendance_df, leave_df):
    # 假设考勤数据和请假数据分别是
    # attendance_df：工号、姓名、刷入日期、刷入时间、刷出日期、刷出时间、班制、班别、星期
    # leave_df：工号、姓名、开始日期、开始时间、结束日期、结束时间、请假时数

    # 示例：读取数据
    # attendance_df = pd.read_excel('attendance.xlsx')
    # leave_df = pd.read_excel('leave.xlsx')

    # 转换时间字段为datetime，方便比较
    attendance_df['刷入日期'] = pd.to_datetime(attendance_df['刷入日期'])
    attendance_df['刷入时间'] = pd.to_datetime(attendance_df['刷入日期'].astype(str) + ' ' + attendance_df['刷入时间'].astype(str), errors='coerce')
    attendance_df['刷出时间'] = pd.to_datetime(attendance_df['刷出日期'].astype(str) + ' ' + attendance_df['刷出时间'].astype(str), errors='coerce')

    leave_df['开始时间'] = pd.to_datetime(leave_df['开始日期'].astype(str) + ' ' + leave_df['开始时间'].astype(str), errors='coerce')
    leave_df['结束时间'] = pd.to_datetime(leave_df['结束日期'].astype(str) + ' ' + leave_df['结束时间'].astype(str), errors='coerce')

    # 定义函数，给每条考勤记录匹配请假并调整刷卡时间
    def adjust_attendance_row(row):
        worker = row['工号']
        check_in_time = row['刷入时间']
        check_out_time = row['刷出时间']
        type_of_work = row['班制']
        time_of_work = row['班别']


        matched_leaves = leave_df[(leave_df['工号.1'] == worker)]
        if matched_leaves.empty: return row

        for i in range(len(matched_leaves)):
            leave_start_time = matched_leaves['开始时间'].iloc[i]
            leave_end_time = matched_leaves['结束时间'].iloc[i]



            if type_of_work == "常日班": # 8-17
                work_start_time = pd.Timestamp("08:00:00")
                work_end_time = pd.Timestamp("17:00:00")
                # 两种情况：普通请假，跨天请假
                # 请假时间  < 打卡时间  <  请假时间
                if leave_start_time >= check_in_time and leave_start_time <= check_out_time:
                    if leave_start_time.time() == work_start_time.time() and check_out_time.date() == leave_end_time.date():
                        row['刷入时间'] = leave_end_time - pd.Timedelta(minutes=np.random.randint(1,16))
                        row['刷出时间'] = work_end_time + pd.Timedelta(minutes=np.random.randint(1,16))
                    elif leave_end_time.time() == work_end_time.time() and check_out_time.date() == leave_end_time.date():
                        row['刷入时间'] = work_start_time - pd.Timedelta(minutes=np.random.randint(1,16))
                        row['刷出时间'] = leave_start_time + pd.Timedelta(minutes=np.random.randint(1,16))

            else:
                if time_of_work == "夜班":
                    work_start_time = pd.Timestamp("20:00:00")
                    work_end_time = pd.Timestamp("08:00:00")
                    if leave_start_time >= check_in_time and leave_start_time <= check_out_time:
                        if leave_start_time.time() == work_start_time.time() and check_out_time.date() == leave_end_time.date():
                            new_time = leave_end_time - pd.Timedelta(minutes=np.random.randint(1, 16))

                            row['刷入日期'] = new_time.date()
                            row['刷入时间'] = new_time
                            row['刷出时间'] = work_end_time + pd.Timedelta(minutes=np.random.randint(1, 16))

                        elif leave_end_time.time() == work_end_time.time() and check_out_time.date() == leave_end_time.date():  # 提早下班
                            new_time = leave_start_time + pd.Timedelta(minutes=np.random.randint(1, 16))

                            row['刷出日期'] = new_time.date()
                            row['刷入时间'] = work_start_time - pd.Timedelta(minutes=np.random.randint(1, 16))
                            row['刷出时间'] = new_time


                else:
                    work_start_time = pd.Timestamp("08:00:00")
                    work_end_time = pd.Timestamp("20:00:00")
                    if leave_start_time >= check_in_time and leave_start_time <= check_out_time:
                        if leave_start_time.time() == work_start_time.time() and check_out_time.date() == leave_end_time.date():
                            row['刷入时间'] = leave_end_time - pd.Timedelta(minutes=np.random.randint(1, 16))
                            row['刷出时间'] = work_end_time + pd.Timedelta(minutes=np.random.randint(1, 16))
                        elif leave_end_time.time() == work_end_time.time() and check_out_time.date() == leave_end_time.date():
                            row['刷入时间'] = work_start_time - pd.Timedelta(minutes=np.random.randint(1, 16))
                            row['刷出时间'] = leave_start_time + pd.Timedelta(minutes=np.random.randint(1, 16))


            if leave_start_time <= (check_in_time + pd.Timedelta(minutes=15)) and (check_out_time - pd.Timedelta(minutes=15)) <= leave_end_time:
                row['刷入时间'] = 'None'
                row['刷出时间'] = 'None'



        return row

    # 应用函数批量处理
    attendance_df = attendance_df.apply(adjust_attendance_row, axis=1)

    # 重新格式化时间为字符串（可选）
    attendance_df['刷入时间'] = pd.to_datetime(attendance_df['刷入时间'], errors='coerce')
    attendance_df['刷出时间'] = pd.to_datetime(attendance_df['刷出时间'], errors='coerce')
    attendance_df['刷入时间'] = attendance_df['刷入时间'].dt.strftime('%H:%M')
    attendance_df['刷出时间'] = attendance_df['刷出时间'].dt.strftime('%H:%M')

    attendance_df['刷入日期'] = pd.to_datetime(attendance_df['刷入日期'], errors='coerce')
    attendance_df['刷出日期'] = pd.to_datetime(attendance_df['刷出日期'], errors='coerce')
    attendance_df['刷入日期'] = attendance_df['刷入日期'].dt.strftime('%Y-%m-%d').astype(str)
    attendance_df['刷出日期'] = attendance_df['刷出日期'].dt.strftime('%Y-%m-%d').astype(str)


    return attendance_df


def get_leave_data(original_data, work_numbers, leave_file):
    leave_pd = pd.read_excel(leave_file)


    leave_pd['开始时间'] = pd.to_datetime(leave_pd['开始时间'], format='%H:%M').dt.time
    leave_pd['结束时间'] = pd.to_datetime(leave_pd['结束时间'], format='%H:%M').dt.time


    mask = (
        (leave_pd['开始时间'] == time(hour=8)) |
        (leave_pd['开始时间'] == time(hour=20)) |
        (leave_pd['结束时间'] == time(hour=17)) |
        (leave_pd['结束时间'] == time(hour=8)) |
        (leave_pd['结束时间'] == time(hour=20))
    )

    leave_pd = leave_pd[mask]
    leave_pd = leave_pd[leave_pd.iloc[:, 0].isin(work_numbers)]
    leave_pd = leave_pd.iloc[:, [0, 1, 2, 3, 4, 5, 6]]

    final_df = generate_leave_data(original_data, leave_pd)
    final_df = final_df.where(pd.notnull(final_df), "None")

    return final_df